feat: reserve list row height with skeleton placeholders#21
Merged
Conversation
PR list and commits list features inject badges only after async GraphQL fetches complete, causing a visible row-height shift after first paint. Synchronously reserve the eventual height with shimmer pill placeholders before fetches start; each feature sweeps its own skeleton class once data arrives. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reserve info-row height at document_start via a stylesheet keyed on <html data-bg-page>, set synchronously by early-sort-redirect.ts and re-applied on every SPA nav. This makes GitHub's first paint already include the row slot, so content.js mounting the real row at document_idle no longer pushes everything down. Also align the reserved height with the real badges' outer box (line-height 18px + 1px transparent border × 2 = 20px). The skeleton pill and ::after slot were 18px, causing a residual 2px shift when the real badge swapped in. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Clear skeletons in a finally block so a rejected fetch can't leave the shimmer pulsing forever. - Replace the per-feature SKELETON_* constants + clearSkeletonsByClass(class) with a single SkeletonKind registry and clearSkeletons(kind) API. - Collapse the duplicate hasReal/hasSkeleton predicates and reduce per-row querySelector calls from four to one. - Tighten detectPageMarker regex to mirror isPRListPage / isCommitsListPage. - Group the shared skeleton background+animation and the three identical ::after reservation blocks in CSS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
reserveInfoRowSkeletons(flags)runs synchronously insideonPageReadybefore any feature's async fetch starts; each feature (pr-branch-names,pr-diff-stats,commit-diff-stats) sweeps its own skeleton class after data resolves.bg-skeleton-pill--branch,bg-skeleton-pill--pr-diff,bg-skeleton-pill--commit-diff) are added toFEATURE_CLASSESso the existing toggle-off cleanup path catches them.feature-pr-review-statusstays unreserved (conditional render — only PRs with threads), but appends into the already-reserved info row, so still no shift.Test plan
pnpm buildsucceeds; loaddist/as unpacked extensionmicrosoft/vscode/pulls) with DevTools → Network → Slow 3G — shimmer pills appear immediately on first paint; real badges swap in with no row-height jump (verify via DevTools → Rendering → Layout Shift Regions)/commits/<branch>) — same expectationfeature-pr-branch-names,feature-pr-diff-stats,feature-commit-diff-statsoff/on in popup — skeletons cleared together with real badges🤖 Generated with Claude Code